import {
  urls,
  serverTypes,
  isBuild,
  serverSource,
  requestTimeoutTime,
  REFRESH_TOKEN,
  isApp,
} from "./constant";
import { getItem } from "@/utils/storage.js";
// import { refreshToken } from "@/apis/auth-api.js";

import ErrorCode from "./error-code";

// 正在请求的接口队列
const HttpQuene = [];

// 存储每个请求id,会被放在http quene中
let id = 0;

// http: 请求使用uview-ui自带的luch-request请求，功能比uni.request完善
const http = uni.$u.http;

// 多个接口地址
const serverTypeValues = Object.values(serverTypes);

const getMessage = (result) => {
  const code = result.code;
  return ErrorCode[code] || result.message || result.msg;
};

// 全局配置
http.setConfig((config) => {
  return config;
});

// 请求拦截
http.interceptors.request.use(
  (config) => {
    // 鉴权处理
    const token = getItem("token");
		console.log(token,'token')
    if (token) {
      config.header["token"] = token;
    }

    config.header["source"] = isApp
      ? "driver_app_new"
      : "driver_miniprogram_new";
    return config;
  },
  (config) => {
    return Promise.reject(config);
  }
);

let isRefreshing = false;
let cacheQuene = [];

//响应拦截
http.interceptors.response.use(
  (response) => {
    return response;
  },
  async (response) => {
    if (response.statusCode === 401) {
			uni.$u.toast('登录过期')
			uni.navigateTo({
				url:'/pages/login/login'
			})
    }
    return Promise.reject(response);
  }
);

const getTaskOptions = (task, options, params, currentId) => {
  const { url } = params;
  HttpQuene.push({
    id: currentId,
    ajaxURL: url,
    task: task,
  });
};

const handlePromiseFinally = (currentId) => {
  // 无论成功还是失败，从正在请求的队列中，移除当前请求
  const index = HttpQuene.findIndex((htp) => htp.id === currentId);
  if (index > -1) {
    HttpQuene.splice(index, 1);
  }
  uni.hideLoading();
  // // 队列中没有请求时，关闭loading
  // if (HttpQuene.length === 0) {
  //   // 解决测试提出  如果app从后台切换至前台时 会出现loading页弹框不消失  卡住的问题
  //   if (store.getters.isAppOnShow) {
  //     setTimeout(() => {
  //       uni.hideLoading();
  //     }, 1500);
  //   } else {
  //     uni.hideLoading();
  //   }
  // }
};

const handlePromiseThen = (resolve, reject, res, params) => {
  const { silentOnError } = params;

  if (res.statusCode === 200) {
    const result = res.data;

    // 将后端的范围值中的code转换为Number
    if (result.code) {
      result.code = +result.code;
    }
    // // 接口失败
    // if (result.code !== 200) {
    //   if (silentOnError) {
    //     resolve(res.data);
    //     return;
    //   }
    //   uni.showToast({
    //     title: getMessage(result),
    //     icon: "none",
    //     // 对于app 错误信息在底部弹出
    //     position: "bottom",
    //   });
    //   reject(res);
    // }
    resolve(res.data);
  }
  reject(res);
};

const service = (params) => {
  let {
    // 预定义参数
    url = "",
    method = "GET",
    data = {},
    headers = {},
    dataType = "json",
    responseType = "text",
    withCredentials = false,
    // 是否在报错时不提示
    silentOnError = false,
    // 是否需要显示loading
    mask = true,
    // 服务类型
    serverType = serverTypes.base,
    // 超时时间
    timeout = requestTimeoutTime,
  } = params;

  if (!serverTypeValues.includes(serverType)) {
    console.error(
      `服务类型错误，serverType当前仅支持${serverTypeValues.join("/")}`
    );
    return;
  }

  // 如果接口前缀不包含/自动填充一个
  if (!url.startsWith("/")) {
    url = "/" + url;
  }

  if (mask) {
    uni.showLoading({
      title: "加载中",
    });
  }

  // 请求自增
  id++;

  return new Promise((resolve, reject) => {
    // 用于判断当前队列中有多少相同url请求的接口
    const apiInQuene = HttpQuene.filter((i) => i.ajaxURL === url);
    if (apiInQuene.length > 1) {
      console.info("当前可能存在重复请求，请确认是否需要");
    }
    // 缓存当前请求的id
    const currentId = id;
    // 与vue.config.js中的proxy匹配
    const envPath = isBuild ? "" : `/${serverSource[serverType]}`;

    let origin = isBuild ? urls[serverType] : "";

    let requestURL = origin + envPath + url;

    // 小程序、app需要带源地址
    // #ifdef MP-WEIXIN || APP-PLUS
    origin = urls[serverType];
    requestURL = origin + url;
    // #endif

    http
      .request({
        url: requestURL,
        method,
        data,
        header: headers,
        timeout,
        dataType,
        responseType,
        withCredentials,
        // 将params传给custom 方便拦截器获取
        custom: {
          ...params,
          currentId,
        },
        getTask: (task, options) =>
          getTaskOptions(task, options, params, currentId),
      })
      .then((res) => {
        handlePromiseFinally(currentId);
        handlePromiseThen(resolve, reject, res, params);
      })
      .catch((res) => {
        handlePromiseFinally(currentId);
        reject(res);
      });
  });
};

const upload = (data) => {
  let {
    // 预定义参数
    url = "",
    params = {},
    filePath,
    file,
    name = "file",
    headers = {},
    formData,
    // 是否在报错时不提示
    silentOnError = false,
    // 是否需要显示loading
    mask = true,
    // 服务类型
    serverType = serverTypes.base,
    // 超时时间
    timeout = requestTimeoutTime,
  } = data;

  if (!serverTypeValues.includes(serverType)) {
    console.error(
      `服务类型错误，serverType当前仅支持${serverTypeValues.join("/")}`
    );
    return;
  }

  // 如果接口前缀不包含/自动填充一个
  if (!url.startsWith("/")) {
    url = "/" + url;
  }
  if (mask) {
    uni.showLoading({
      title: "加载中",
    });
  }

  // 请求自增
  id++;
  return new Promise((resolve, reject) => {
    // 用于判断当前队列中有多少相同url请求的接口
    const apiInQuene = HttpQuene.filter((i) => i.ajaxURL === url);
    if (apiInQuene.length > 1) {
      console.info("当前可能存在重复请求，请确认是否需要");
    }
    // 缓存当前请求的id
    const currentId = id;
    // 与vue.config.js中的proxy匹配
    const envPath = isBuild ? "" : `/${serverSource[serverType]}`;

    let origin = isBuild ? urls[serverType] : "";

    let requestURL = origin + envPath + url;

    // 小程序、app需要带源地址
    // #ifdef MP-WEIXIN || APP-PLUS
    origin = urls[serverType];
    requestURL = origin + url;
    // #endif

    http
      .upload(requestURL, {
        params,
        filePath,
        file,
        name,
        timeout,
        formData,
        header: headers,
        getTask: (task, options) =>
          getTaskOptions(task, options, params, currentId),
      })
      .then((res) => {
        handlePromiseFinally(currentId);
        handlePromiseThen(resolve, reject, res, data);
      })
      .catch((res) => {
        handlePromiseFinally(currentId);
        reject(res);
      });
  });
};

export default {
  get(params) {
    return service({
      ...params,
      method: "GET",
    });
  },
  post(params) {
    return service({
      ...params,
      method: "POST",
    });
  },
  delete(params) {
    return service({
      ...params,
      method: "DELETE",
    });
  },
  put(params) {
    return service({
      ...params,
      method: "PUT",
    });
  },
  upload(params) {
    return upload({
      ...params,
    });
  },
};
